﻿using System;
using System.Collections.Generic;
using System.Text;
using Sinacor.Infra.UI.Security.Services;
using Sinacor.Infra.UI.Common;

namespace Sinacor.Infra.ServiceAccess
{
    /// <summary>
    /// Classe responsável por encapsular a geração dos proxies de acesso aos serviços
    /// </summary>
    /// <typeparam name="TProxy"></typeparam>
    public class ServiceClient<TProxy> : IDisposable
    {
        //armazenar uma instancia para o service instance
        private ServiceInstance<TProxy> _serviceInstance;
        private AuthenticationParm _authenticationParm;
        private string _endpointName;
        private string _configFilePath;


        /// <summary>
        /// Bloquear o construtor padão, de forma a permitir apenas a utilização
        /// do construtor customizado
        /// </summary>
        private ServiceClient()
        {
        }

        /// <summary>
        /// Contrutor da classe
        /// </summary>
        /// <param name="authenticationParm">Parâmetros de autenticação</param>
        /// <param name="endpointName">Nome do endpoint a ser utilizado</param>
        /// <param name="configFilePath">Caminho do arquivo de configuração de endpoints</param>
        public ServiceClient(AuthenticationParm authenticationParm, string endpointName, string configFilePath)
        {
            if (authenticationParm == null)
                throw new ArgumentNullException("authenticationParm");

            if (string.IsNullOrEmpty(endpointName))
                throw new ArgumentNullException("endPointName");

            if (string.IsNullOrEmpty(configFilePath))
                throw new ArgumentNullException("configFilePath");


            _authenticationParm = authenticationParm;
            _endpointName = endpointName;
            _configFilePath = configFilePath;
        }

        /// <summary>
        /// Retorna uma instância do proxy de acesso ao serviço.
        /// </summary>
        /// <param name="authenticationParm">Parâmetros de autenticação</param>
        /// <param name="endpointName">Nome do endpoint a ser utilizado</param>
        /// <param name="configFilePath">Caminho do arquivo de configuração de endpoints</param>
        /// <returns></returns>
        public TProxy CreateProxy()
        {
            //se já houver uma instância criada
            if (_serviceInstance != null)
                _serviceInstance.Dispose();

            //criar uma nova sessionInformation, indicando que não será ativado o servico de recebimento de mensagens
            SessionInformation sessionInformation = new SessionInformation(false);

            sessionInformation.LoginName = _authenticationParm.LoginName;
            sessionInformation.Password = _authenticationParm.Password;
            sessionInformation.CompanyId = _authenticationParm.CompanyId;
            sessionInformation.TokenId = Guid.NewGuid().ToString();

            //criar uma instancia do serviceInstance que sera utilizada para retornar o proxy de acesso ao servico
            _serviceInstance = new ServiceInstance<TProxy>();

            return _serviceInstance.TryGetInstance(sessionInformation, _endpointName, _configFilePath);
        }

        #region IDisposable Members
        /// <summary>
        /// Realiza a liberação dos recursos alocados pela classe
        /// </summary>
        public void Dispose()
        {
            if (_serviceInstance != null)
            {
                _serviceInstance.Dispose();
                _serviceInstance = null;
            }
        }
        #endregion
    }
}
